// Problem: 
// Contest: 
// URL: 
// Memory Limit: 
// Time Limit: 
// #pragma GCC optimize("Ofast")
// #pragma GCC optimize("unroll-loops")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
	return s*w;
}
int n,m;
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};
struct pos
{
	int x,y,z;
	pos(int xx,int yy,int zz)
	{
		x=xx,y=yy,z=zz;
	}
};
struct tr
{
	int x1,y1;
	int x2,y2;
	bool f=0;
};
vector<tr> t(30);
vector<vector<char>> v;
vector<vector<bool>> f;
signed main()
{
	cin>>n>>m;
	int a,b,c,d;
	v=vector<vector<char>> (n+1,vector<char>(m+1));
	f=vector<vector<bool>> (n+1,vector<bool>(m+1));
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			cin>>v[i][j];
			if(v[i][j]=='@')a=i,b=j;
			if(v[i][j]=='=')c=i,d=j;
			if(v[i][j]>='A'&&v[i][j]<='Z')
			{
				int tmp=v[i][j]-'A';
				if(t[tmp].f==0)
				{
					t[tmp].x1=i;
					t[tmp].y1=j;
					t[tmp].f=1;
				}
				else 
				{
					t[tmp].x2=i;
					t[tmp].y2=j;
				}
			}	
		}
	queue<pos> q;
	q.push(pos(a,b,0));
	while(!q.empty())
	{
		pos p=q.front();
		q.pop();
		int x=p.x,y=p.y,z=p.z;
		if(x==c&&y==d)
		{
			cout<<z;
			return 0;
		}
		//f[x][y]=1;
		for(int i=0;i<4;i++)
		{
			int xx=x+dx[i],yy=y+dy[i],zz=z+1;
			if(xx<1||xx>n||yy<1||yy>m||v[xx][yy]=='#'||f[xx][yy])continue;
			f[xx][yy]=1;
			if(v[xx][yy]>='A'&&v[xx][yy]<='Z')
			{
				//f[xx][yy]=1;
				int tmp=v[xx][yy]-'A';
				if(xx==t[tmp].x1&&yy==t[tmp].y1)
				{
					xx=t[tmp].x2,yy=t[tmp].y2;
				}
				else
				{
					xx=t[tmp].x1,yy=t[tmp].y1;
				}
			}
			//f[xx][yy]=1;
			q.push(pos(xx,yy,zz));
		}
	}
	return 0;
}
